/**
 * Ingenius-Group S.A.S
 *
 * Project: SAU
 * File: EditAssignedInstrumentPresenter.java
 * Date: 07/02/2011
 */

package com.ingenius.sau.client.presenter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.ingenius.sau.client.AppController;
import com.ingenius.sau.client.Constants;
import com.ingenius.sau.client.event.ListAssignedInstrumentsEvent;
import com.ingenius.sau.client.service.CoreServiceAsync;
import com.ingenius.sau.client.view.Display;
import com.ingenius.sau.shared.model.core.Indicator2Evaluate;
import com.ingenius.sau.shared.model.instruments.AssignedInstrument;
import com.ingenius.sau.shared.model.instruments.Document;
import com.ingenius.sau.shared.model.instruments.Instrument;
import com.ingenius.sau.shared.model.instruments.Question;
import com.ingenius.sau.shared.model.users.Group;

/**
 * Class <strong>EditAssignedInstrumentPresenter</strong>
 * 
 * @author Jesus David
 * @version 0.1
 */
public class EditAssignedInstrumentPresenter implements EditPresenter {

	public interface EditAssignedInstrumentDisplay extends Display {

		String getInstrumentType();

		void setInstrumentType(String type);

		void setInstrumentsTypes(List<String> types);

		String getInstrumentId();

		void setInstrumentId(String instrumentId);

		void setInstruments(List<Instrument> instruments);

		String getGroupId();

		void setGroupId(String groupId);

		void setGroups(List<Group> groups);

		void enableComboGroups(boolean state);

		Double getScore();

		void setScore(Double score);

		void show();

		void hide();
	}

	private final HandlerManager eventBus;
	private final CoreServiceAsync rpcService;
	private final EditAssignedInstrumentDisplay display;
	private AssignedInstrument assignedInstrument;

	public EditAssignedInstrumentPresenter(HandlerManager eventBus,
			CoreServiceAsync rpcService, EditAssignedInstrumentDisplay display,
			String assignedInstrumentId) {

		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = display;
		display.setPresenter(this);
		loadInstrumentsTypes();
		loadGroups();

		if (assignedInstrumentId == null) {
			assignedInstrument = new AssignedInstrument();

		} else {
			loadBean(assignedInstrumentId);
		}

	}

	private void loadInstrumentsTypes() {
		List<String> types = new ArrayList<String>();
		types.add(Instrument.TYPE_DOCUMENT);
		types.add(Instrument.TYPE_QUESTION);
		display.setInstrumentsTypes(types);
	}

	private void loadGroups() {
		rpcService.loadAllGroups(new AsyncCallback<List<Group>>() {
			@Override
			public void onSuccess(List<Group> result) {
				display.setGroups(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Error loading groups. "
						+ caught.getMessage());
			}
		});
	}

	public void loadInstruments() {
		if (display.getInstrumentType().equals(Instrument.TYPE_DOCUMENT)) {
			rpcService.loadAllDocs(new AsyncCallback<List<Document>>() {
				@Override
				public void onSuccess(List<Document> result) {
					List<Instrument> docs = new ArrayList<Instrument>(result);
					display.setInstruments(docs);
					display.enableComboGroups(false);
				}

				@Override
				public void onFailure(Throwable caught) {
					System.out.println("Error loading documents. "
							+ caught.getMessage());
				}
			});

		} else {
			rpcService.loadAllQuestions(new AsyncCallback<List<Question>>() {
				@Override
				public void onSuccess(List<Question> result) {
					List<Instrument> questions = new ArrayList<Instrument>(
							result);
					display.setInstruments(questions);
					display.enableComboGroups(true);
				}

				@Override
				public void onFailure(Throwable caught) {
					System.out.println("Error loading questions. "
							+ caught.getMessage());
				}
			});
		}
	}

	private void loadBean(String assignedInstrumentId) {
		AppController.setStatusMessage("Loading...");
		rpcService.getAssignedInstrument(assignedInstrumentId,
				new AsyncCallback<AssignedInstrument>() {
					@Override
					public void onSuccess(AssignedInstrument result) {
						if (result == null) {
							onFailure(new Throwable("Database error"));
							return;
						}
						assignedInstrument = result;
						AppController.setAttribute(
								Constants.COOKIE_INSTRUMENT_ID,
								assignedInstrument.getInstrumentId());
						display.setInstrumentType(assignedInstrument
								.getInstrumentType());
						display.setGroupId(assignedInstrument.getGroupId());
						display.setScore(assignedInstrument.getScore());
						hideStatusMessage();
					}

					@Override
					public void onFailure(Throwable caught) {
						GWT.log(Constants.MESSAGE_FAILED_GET
								+ AssignedInstrument.class.getName(), caught);
						assignedInstrument = new AssignedInstrument();
						// TODO i18n
						String failedMessage = "Failed to retrieve assigned instrument";
						display.showInfo(failedMessage);
						hideStatusMessage();
					}

					void hideStatusMessage() {
						AppController.hideStatusMessage();
					}
				});
	}

	@Override
	public void doSaveOrUpdate() {
		assignedInstrument.setCreatedDate(new Date());
		assignedInstrument.setScore(display.getScore());
		assignedInstrument.setInstrumentType(display.getInstrumentType());
		assignedInstrument.setInstrumentId(display.getInstrumentId());
		assignedInstrument.setGroupId(display.getGroupId());
		String currentIndicator2EvaluateId = (String) AppController
				.getAttribute(Constants.CURRENT_INDICATOR2EVALUATE_ID);
		assignedInstrument.setIndicator2Evaluate(new Indicator2Evaluate(
				currentIndicator2EvaluateId));

		// TODO i18n
		final String failedMessage = "Failed to save assigned instrument";
		final String successMessage = "Assigned Instrument saved sucessfully";

		display.hide();
		AppController.setStatusMessage("Saving...");
		rpcService.saveOrUpdateAssignedInstrument(assignedInstrument,
				new AsyncCallback<Boolean>() {
					@Override
					public void onSuccess(Boolean result) {
						if (result) {
							eventBus.fireEvent(new ListAssignedInstrumentsEvent());
							display.showInfo(successMessage);
							hideStatusMessage();

						} else {
							onFailure(new Throwable("Database error"));
						}
					}

					@Override
					public void onFailure(Throwable caught) {
						GWT.log(Constants.MESSAGE_FAILED_SAVE
								+ AssignedInstrument.class.getName(), caught);
						display.showInfo(failedMessage);
						hideStatusMessage();
					}

					void hideStatusMessage() {
						AppController.hideStatusMessage();
					}
				});
	}

	@Override
	public void go(HasWidgets container) {
		display.show();
	}

}
